package com.zyz.framework.interceptor;


import com.zyz.common.annotation.ValidateToken;
import com.zyz.framework.web.service.ApiTokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.AsyncHandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 前台用户token验证拦截器
 * 
 * @author zyz
 * @date 2021年11月28日
 */
public class ApiTokenInterceptor implements AsyncHandlerInterceptor {

    @Autowired
    private ApiTokenService tokenSrv;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        HandlerMethod handlerMethod = (HandlerMethod) handler;

        boolean validateToken = isValidateToken(handlerMethod);

        if (!validateToken) {
            return true;
        }

        tokenSrv.checkLogin(request);

        return true;
    }

    /**
     * 是否需要验证登录
     * 
     * @author yilabao
     * @date 2021年1月28日
     * @param handlerMethod
     * @return boolean
     */
    private boolean isValidateToken(HandlerMethod handlerMethod) {
        ValidateToken validateToken = getValidateToken(handlerMethod);
        if (validateToken == null) {
            return true;
        }
        return validateToken.isValidate();
    }

    /**
     * 先获取方法注解，如果没有，再获取类注解
     * 
     * @author yilabao
     * @date 2021年1月28日
     * @param handlerMethod
     * @return ValidateToken
     */
    private ValidateToken getValidateToken(HandlerMethod handlerMethod) {
        Method method = handlerMethod.getMethod();
        if (method.isAnnotationPresent(ValidateToken.class)) {
            return method.getAnnotation(ValidateToken.class);
        }
        Class<?> type = handlerMethod.getBeanType();
        if (type.isAnnotationPresent(ValidateToken.class)) {
            return type.getAnnotation(ValidateToken.class);
        }
        return null;
    }

}